/*
 * FileContainer.cpp
 *
 *  Created on: May 1, 2010
 *      Author: Lukasz Spintzyk
 */

#include "FileContainer.h"
#include "File.h"
#include "InodeReader.h"
#include "BlockReader.h"


// TODO make it thread safe
uint64_t FileContainer::s_file_id = 1;

FileContainer::FileContainer(InodeManager& inodeMgr, BlockManager& blockMgr)
	:d_inodeMgr(inodeMgr)
	,d_blockMgr(blockMgr)
{

}

FileContainer::~FileContainer() {
}

uint64_t FileContainer::addFile(const std::string& path, InodePtr fileInode)
{
	uint64_t fh = getUniqueFileHandle();
	FilePtr file;//(new File(path, fileInode, d_inodeMgr, d_blockMgr));
	file.reset(new File(path, fileInode, d_inodeMgr, d_blockMgr));
	d_files.insert(std::make_pair(fh, file));
	d_path2fh.insert(std::make_pair(path, fh));
	return fh;
}

uint64_t FileContainer::getUniqueFileHandle()
{
	return s_file_id++;
}

bool FileContainer::hasFile(const std::string& path)
{
	return d_path2fh.find(path) != d_path2fh.end();
}

bool FileContainer::hasFile(uint64_t fh)
{
	return d_files.find(fh) != d_files.end();
}


FilePtr FileContainer::getFile(const std::string& path)
{
	uint64_t fh = (*d_path2fh.find(path)).second;
	return (*d_files.find(fh)).second;
}

FilePtr FileContainer::getFile(uint64_t fh)
{
	return (*d_files.find(fh)).second;
}

void FileContainer::release(uint64_t fh)
{
	for(std::map<std::string,  uint64_t>::iterator
		cit = d_path2fh.begin();
		cit != d_path2fh.end();
		++cit)
		{
			if (fh == (*cit).second)
			{
				d_path2fh.erase(cit);
			}
		}

	d_files.erase(d_files.find(fh));
}

bool FileContainer::renameFile(const std::string& path, const std::string newPath)
{
	if (hasFile(path) && (!hasFile(newPath)))
	{
		uint64_t fh = d_path2fh[path];
		d_path2fh[newPath] = fh;
		d_path2fh.erase(path);
		return true;
	}
	return false;
}

uint64_t FileContainer::getFileHandle(const std::string& path)
{
	return (*d_path2fh.find(path)).second;
}

void FileContainer::removeFileIfExist(const std::string& path)
{
	if (hasFile(path))
	{
		uint64_t fh = d_path2fh[path];
		d_path2fh.erase(d_path2fh.find(path));
		d_files.erase(d_files.find(fh));
	}
}
